%===============================================================
%=        Noise Cancellation With Adaptive Filters             =
%===============================================================
%=   The Coeficients Of The Adaptive Filter Are Calculated     =
%=                        Using The                            =
%=          BASIC LEAST MEAN SQUARE (LMS) ALGORITHM            =
%=         The Algorithm Developed By Widrow In 1975.          =
%===============================================================
%= 						     Notes                                =
%=                    -------------                            =
%=                                                             =
%= In The Variable MU Is Stored The Value That Specifies       =
%= What Is The Rate Of Convergence For The Adaptive Algorithm. =
%= The Condition For Convergence Is:    0< MU >1/EV(Max)       = 
%= Which Means That MU Should Be Less Than The Smallest        =
%= Eigenvalue of the unknown Transfer Function For The         =
%= Adaptive Filter To Be Properly Conditioned. 						=
%=                                                             =
%= FLENGTH is the order of the filter.                         =
%=                                                             =
%= NITERATIONS is the number of iterations to take place.      =
%=                                                             =
%= ISIGNAL is the input signal to the system.                  =
%=                                                             =
%= NOISE0 And NOISE are two independent noise sources.         =
%===============================================================

clc
clear
%The Convergence Factor.
MU = 0.01; 								 
%The Filter Length.
FLength = 40; 							
%The Number Of Iterations.
NIterations = 1000; 					 
%The Input White Noise.
Noise = 0.7*randn(NIterations,1);
MSE = 0;

for n=1:NIterations 
   %The Input Signal.
   InputSignal = (2*sin(pi/2*linspace(1,10,1000)))+ (2/3*sin(3*pi/2*linspace(1,10,1000)))+ (2/5*sin(5*pi/2*linspace(1,10,1000)))+ (2/7*sin(7*pi/2*linspace(1,10,1000)))+(2/9*sin(9*pi/2*linspace(1,10,1000)));
end

figure (1);
plot(InputSignal);
title('The Input Signal');
ylabel('Amplitude');
xlabel('Time');
grid on

%The Signal Plus The Noise.
SignalPlusNoise = InputSignal' + Noise; 

%The Time Domain Of The Input Noisy Signal.
FreqXAxis = 0:length(SignalPlusNoise)-1;
figure(2);
plot(FreqXAxis,SignalPlusNoise,'b');
title('The Noisy Signal');
xlabel('Time');
ylabel('Amplitude');
grid on

%===================================================
%= The Adaptive Algorithm LMS (Least Mean Squares) =
%===================================================
%= START =
%=========

%The Initial Input.
INoise = 0*(1:FLength)'; 
%The initial Filter Coefficients.
FCoeff = 0*(1:FLength); 

%Calculation Of The First Iteration.
OSignal = FCoeff * INoise;
Error = Noise(1)- OSignal;			
MSE(1) = Error;
FCoeff = FCoeff +(2 * MU * Error * INoise');

%Calculation OF The Nth Iteration.
for j = 1:NIterations
   INoise(1) = Noise(j);                         
   OSignal = FCoeff * INoise;                     
	Error = SignalPlusNoise(j) - OSignal;          
	MSE(j) = Error;
	FCoeff = FCoeff + (2 * MU * Error * INoise');
end 

%=======
%= END =
%===================================================
%= The Adaptive Algorithm LMS (Least Mean Squares) =
%===================================================

%The Filtered Signal
figure(3);
plot(1:1000,MSE,'b');
title('The Filtered Signal');
xlabel('Frequency');
ylabel('Magnitude');
grid on

%The Frequency Spectrums For The Unfiltered and Filtered Signals.
Time = 0:8000/(512-1):8000;
figure(4);
plot(Time,abs(fft(SignalPlusNoise,512))./512,'b');
title('Fast Fourier Transform (Frequency Domain) For The Noisy Signal');
xlabel('Frequency');
ylabel('Magnitude');
grid on

figure(5);
plot(Time,abs(fft(MSE,512))./512,'b');
title('Fast Fourier Transform (Frequency Domain) For The Filtered Signal');
xlabel('Frequency');
ylabel('Magnitude');
grid on

%The Time Domain For The Mean Square Error.
figure(6);
plot(FreqXAxis,(InputSignal-MSE).^2,'b');
title('The Mean Square Error');
xlabel('Time');
ylabel('Magnitude');
grid on

%The Final Filter Coeficients, The MSE And The Signal-To-Noise Ratio.
disp('Estimated Filter Coefficients FCoeff =');
disp(FCoeff');

disp('Mean Squared Error (MSE) Error =');
disp(abs(Error));

SignalToNoiseRatioUnfiltered = 10*log10(sum(abs(fft(InputSignal)).^2)/sum(abs(fft(SignalPlusNoise-InputSignal')).^2));
disp('Signal To Noise Ratio For The Unfiltered Signal =');
disp(SignalToNoiseRatioUnfiltered);

SignalToNoiseRatioFiltered = 10*log10(sum(abs(fft(InputSignal)).^2)/sum(abs(fft(MSE-InputSignal)).^2));
disp('Signal To Noise Ratio For The Filtered Signal =');
disp(SignalToNoiseRatioFiltered);
